package com.zhao.dota.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhao.dota.bo.PlayerMatchSummary;
import com.zhao.dota.bo.PlayerPeers;
import com.zhao.dota.common.contant.CommonConst;
import com.zhao.dota.mapper.MatchPlayerMapper;
import com.zhao.dota.model.DotaMatch;
import com.zhao.dota.model.Hero;
import com.zhao.dota.model.MatchPlayer;
import com.zhao.dota.model.Player;
import com.zhao.dota.service.HeroService;
import com.zhao.dota.service.MatchPlayerService;
import com.zhao.dota.service.PlayerService;
import com.zhao.dota.vo.HeroWinRate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MatchPlayerServiceImpl extends ServiceImpl<MatchPlayerMapper, MatchPlayer> implements MatchPlayerService {

    @Resource
    private HeroService heroService;
    @Resource
    private PlayerService playerService;

    @Override
    public int saveList(DotaMatch match, List<MatchPlayer> list) {
        int count = 0;
        List<Long> steamIds = list.stream().map(MatchPlayer::getSteamId).collect(Collectors.toList());
        Map<Long, Player> playerMap = playerService.getOrCreatePlayers(match, steamIds);

        for (MatchPlayer player : list) {
            Hero hero = heroService.getByName(player.getHeroName());
            Player p = playerMap.get(player.getSteamId());
            if (p != null) {
                player.setAvatar(p.getAvatar());
                player.setAvatarFull(p.getAvatarFull());
                player.setShortSteamId(p.getShortSteamId());
                player.setPlayerId(p.getId());
            }
            player.setHeroLocalizedName(hero.getLocalizedName());
            player.setHeroId(hero.getId());
            LambdaQueryWrapper<MatchPlayer> query = Wrappers.lambdaQuery(MatchPlayer.class)
                    .eq(MatchPlayer::getMatchId, player.getMatchId())
                    .eq(MatchPlayer::getSteamId, player.getSteamId());
            MatchPlayer old = getOne(query);
            if (old == null) {
                count += baseMapper.insert(player);
            } else {
                BeanUtil.copyProperties(player, old, CommonConst.IGNORE_NULL_VALUE);
                count += baseMapper.updateById(old);
                player.setId(old.getId());
            }
        }
        return count;
    }

    @Override
    public List<MatchPlayer> findByMatchId(Integer matchId) {
        LambdaQueryWrapper<MatchPlayer> query = Wrappers.lambdaQuery(MatchPlayer.class)
                .eq(MatchPlayer::getMatchId, matchId);
        return list(query);
    }

    public MatchPlayer count(Player player, int limit) {
        return baseMapper.countWinRate(player.getSteamId(), limit);
    }

    @Override
    public Page<PlayerMatchSummary> page(Page page, Long steamId) {
        return baseMapper.page(page, steamId);
    }

    @Override
    public Page<PlayerPeers> peersOrEnemies(Page page, Long steamId, boolean peer) {
        return baseMapper.peersOrEnemies(page, steamId, peer);
    }

    @Override
    public Page<HeroWinRate> groupByPlayerHero(Integer playerId, Page page) {
        return baseMapper.groupByPlayerHero(page, playerId);
    }

    @Override
    public Page<HeroWinRate> groupByHero(Page page, LocalDateTime startTime, LocalDateTime endTime) {
        return baseMapper.groupByHero(page, startTime, endTime);
    }

}
